package leo.peersim.paxos;

import java.util.HashMap;

import leo.peersim.common.LogicalClock;

import peersim.core.CommonState;
import peersim.core.Network;
import peersim.core.Node;

/**
 * Paxos agent
 * 
 * @author leo
 * @version June 18, 2009
 */
public abstract class PaxosAgent {
	
	protected Paxos container; //?? cross-cutting concern?
	
	private String name = "genericAgent";
	
	public PaxosAgent(Paxos container) {
		this.container = container;
	}

	@Deprecated
	protected void stopSimulation() {
		//stopSimulation.signal();
		//this.stopSimulation = true;
		this.notifyAll();
	}
	
	protected String pp() {
		//return CommonState.getTime() + "\t[" + CommonState.getNode().getID() + "] " + container.getLogicalClock() + "\t" +  this.getName() + " - ";
		return CommonState.getTime() + "\t" + container.getLogicalClock() + " [" + CommonState.getNode().getID() + "] " +  this.getName() + " - ";
	}
	
	protected String getName() {
		return name;
	}
	
	protected void manage(PaxosMessage message) {
		//TODO
	}

}

class Ballots<T> extends HashMap<Node, T> {
	
	private static final long serialVersionUID = -6076027170594121290L;
	
	public boolean hasQuorum() {
		int quorum = (int) Math.floor(Network.size()/2) + 1;
		if (this.size()>=quorum) {
			return true;
		}
		return false;
	}
	
}

class PromisedBallots extends Ballots<Promise> {

	private static final long serialVersionUID = -197272023013357830L;
	
	public LogicalClock getLargestAcceptNum() {
		return null;
	}
	
	public long getLargestValue() {
		long largestValue = 0;
		for (Promise p : this.values()) {
			largestValue = Math.max(largestValue, p.getLatestAcceptedValue());
		}
		return largestValue;
	}

	public long getSmallerValue() {
		long smallerValue = Long.MAX_VALUE;
		for (Promise p : this.values()) {
			smallerValue = Math.min(smallerValue, p.getLatestAcceptedValue());
		}
		return smallerValue;
	}
}

class AcceptedBallots extends Ballots<Accept> {
	
	private static final long serialVersionUID = 2436739934836991141L;

}

